"""
策略基类模块
"""
import pandas as pd
from abc import ABC, abstractmethod
from loguru import logger


class Strategy(ABC):
    """
    策略基类，定义了策略的基本接口

    Parameters
    ----------
    feed : yhlz_backtest.feed.base.Feed
        数据源对象
    broker : yhlz_backtest.broker.Broker
        经纪人对象
    """

    def __init__(self, feed, broker):
        self._feed = feed
        self._broker = broker

    # Only valid for testing purposes.
    def _setBroker(self, broker):
        self._broker = broker

    def get_positions(self):
        return self._broker.positions

    def get_result(self):
        return self._broker.equity

    def current_datetime(self):
        """
        获取当前日期时间
        """
        return self._feed.current_datetime

    @staticmethod
    def process_feed(df):
        """
        会被传给get feed，用来在最初，还是csv文件时的数据进行处理，以便加上技术指标，避免，在循环中计算，效率太低，默认什么也不干
        """
        pass
    
    @abstractmethod
    def next():
        """
        程序主逻辑，类似与on bar
        """
        pass

    def run(self):
        """
        运行策略
        """

        while True:
            self.next()  # 调用策略逻辑
            self._broker.update()  # 更新broker状态
            if self._feed.next() is False:
                logger.info("策略执行完成，没有更多数据")
                break
            
    def buy(self, instrument, quantity, offset, price=None):
        """
        买入
        
        Parameters
        ----------
        instrument : str
            交易品种代码
        quantity : float
            数量
        price : float, optional
            价格，如果为None则为市价单
        stop_price : float, optional
            止损价格
            
        Returns
        -------
        int
            订单ID
        """
        from yhlz_backtest.broker import OrderType, OrderAction, OrderOffset
        
        if price is None:
            # 市价单
            order_type = OrderType.MARKET
        elif price is not None:
            # 限价单
            order_type = OrderType.LIMIT
        
        order_id = self._broker.order(
            instrument=instrument,
            order_type=order_type,
            action=OrderAction.BUY,
            offset=offset,
            quantity=quantity,
            price=price,
        )
        
        logger.info(f"提交买入订单: {instrument}, 数量={quantity}, 价格={price}, 订单ID={order_id}")
        
        return order_id
    
    def sell(self, instrument, quantity, offset, price=None):
        """
        卖出
        
        Parameters
        ----------
        instrument : str
            交易品种代码
        quantity : float
            数量
        price : float, optional
            价格，如果为None则为市价单
        stop_price : float, optional
            止损价格
            
        Returns
        -------
        int
            订单ID
        """
        from yhlz_backtest.broker import OrderType, OrderAction
        
        if price is None:
            # 市价单
            order_type = OrderType.MARKET
        elif price is not None:
            # 限价单
            order_type = OrderType.LIMIT
        
        order_id = self._broker.order(
            instrument=instrument,
            order_type=order_type,
            action=OrderAction.SELL,
            offset=offset,
            quantity=quantity,
            price=price,
        )
        
        logger.info(f"提交卖出订单: {instrument}, 数量={quantity}, 价格={price}, 订单ID={order_id}")
        
        return order_id
    

